#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;

int main() {
  Mat src = imread("../images/2.jpg");
  Mat dst;
  if (src.empty()) {
    cout << "could not load image.." << endl;
    return -1;
  }
  namedWindow("opencv setup demo", CV_WINDOW_AUTOSIZE);
  imshow("opencv setup demo", src);

  // contrast and brigthtness changes
  int height = src.rows;
  int width = src.cols;
  dst = Mat::zeros(src.size(), src.type());
  float alpha = 1.2;
  float beta = 15;

  Mat m1;
  src.convertTo(m1, CV_32F);
  for (int row = 0; row < height; row++) {
    for (int col = 0; col < width; col++) {
      if (src.channels() == 3) {
        float b = m1.at<Vec3f>(row, col)[0];  // blue
        float g = m1.at<Vec3f>(row, col)[1];  // green
        float r = m1.at<Vec3f>(row, col)[2];  // red

        // output
        dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b * alpha + beta);
        dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g * alpha + beta);
        dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r * alpha + beta);
      } else if (src.channels() == 1) {
        float v = src.at<uchar>(row, col);
        dst.at<uchar>(row, col) = saturate_cast<uchar>(v * alpha + beta);
      }
    }
  }
  char output_title[] = "contrast and brightness change demo";
  namedWindow(output_title, CV_WINDOW_AUTOSIZE);
  imshow(output_title, dst);

  waitKey(0);
  return 0;
}